#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <atomic>
#include <random>
#include <iomanip>
#include "logger.hpp"

namespace im
{
    std::string uuid(){
        // 生成10个16进制数组成的随机字符:由 6(随机数)+4(递增数)
        // 1.生成6个随机数
        std::random_device rd;//实例化设备随机数对象-用于生成设备随机数
        std::mt19937 generator(rd());//以设备随机数为种子，实例化伪随机数对象
        std::uniform_int_distribution<int> distribution(0,255); //限定数据范围
        std::stringstream ss;
        for (int i = 0; i < 6; i++) {
            if (i == 2) ss << "-";
            ss << std::setw(2) << std::setfill('0') << std::hex << distribution(generator);
        }
        ss << "-";
        // 2.生成4个递增数
        static std::atomic<short> idx(0);
        short tmp = idx.fetch_add(1);
        ss << std::setw(4) << std::setfill('0') << std::hex << tmp;
        return ss.str();
    }

    std::string verify_code(){
        std::random_device rd;//实例化设备随机数对象-用于生成设备随机数
        std::mt19937 generator(rd());//以设备随机数为种子，实例化伪随机数对象
        std::uniform_int_distribution<int> distribution(1000,9999); //限定数据范围

        return std::to_string(distribution(generator));
    }

    bool readFile(const std::string& fileName, std::string& body){
        std::ifstream ifs(fileName, std::ios::binary | std::ios::in);
        if(ifs.is_open() == false){
            LOG_CRITICAL("打开文件 {} 失败！", fileName);
            ifs.close();
            return false;
        }
        // 跳到文件末尾，统计文件长度，再跳转回来进行读取
        ifs.seekg(0 ,std::ios::end);
        size_t flen = ifs.tellg();
        ifs.seekg(0, std::ios::beg);
        // 调整字符串大小，以便存储文件内容
        body.resize(flen);
        ifs.read(&body[0], flen);
        if(ifs.good() == false){
            LOG_CRITICAL("读取文件 {} 数据失败！", fileName);
            ifs.close();
            return false;
        }
        ifs.close();
        return true;
    }

    bool writeFile(const std::string& fileName, const std::string& body){
        std::ofstream ofs(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
        if (ofs.is_open() == false) {
            LOG_CRITICAL("打开文件 {} 失败！", fileName);
            return false;
        }
        ofs.write(body.c_str(), body.size());
        if (ofs.good() == false) {
            LOG_CRITICAL("读取文件 {} 数据失败！", fileName);
            ofs.close();
            return false;
        }
        ofs.close();
        return true;
    }
} // namespace im
